/*****************************************************************************
Copyright 2006 Kervin L. Pierre
    EMAIL: otlkcon@adevsoft.com

This file is part of Otlkcon.

Otlkcon is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.

Otlkcon is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Lesser GNU General Public License for more details.

You should have received a copy of the Lesser GNU General Public License
along with Otlkcon; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*******************************************************************************/

#include "stdafx.h"
#include "otlkcon_compare_props.h"

HRESULT otlkcon_compare_props( ULONG relop, 
                                  LPSPropValue propVal1, LPSPropValue propVal2,
                                  BOOL *result)
{
    HRESULT retVal = S_OK;
    BOOL failed = FALSE;
    ULONG res1;

    if( PROP_TYPE(propVal1->ulPropTag) != PROP_TYPE(propVal2->ulPropTag) )
    {
        // same types only please 
        return MAPI_E_TOO_COMPLEX;
    }

    switch( PROP_TYPE(propVal1->ulPropTag) )
    {
        // case PT_I2: 
    case PT_SHORT: // i 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.i >= propVal2->Value.i )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.i > propVal2->Value.i )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.i <= propVal2->Value.i )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.i < propVal2->Value.i )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.i != propVal2->Value.i )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.i == propVal2->Value.i )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.i == propVal2->Value.i )
            {
                *result = TRUE;
            }
            break;
        }
        break;

        // case PT_I4: 
    case PT_LONG:  // l or ul - which one? this may be a problem 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.l >= propVal2->Value.l )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.l > propVal2->Value.l )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.l <= propVal2->Value.l )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.l < propVal2->Value.l )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.l != propVal2->Value.l )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.l == propVal2->Value.l )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.l == propVal2->Value.l )
            {
                *result = TRUE;
            }
            break;
        }
        break;


        // case PT_R4: 
    case PT_FLOAT: // flt 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.flt >= propVal2->Value.flt )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.flt > propVal2->Value.flt )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.flt <= propVal2->Value.flt )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.flt < propVal2->Value.flt )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.flt != propVal2->Value.flt )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.flt == propVal2->Value.flt )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.flt == propVal2->Value.flt )
            {
                *result = TRUE;
            }
            break;
        }
        break;

        // case PT_R8: 
    case PT_DOUBLE: // dbl 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.dbl >= propVal2->Value.dbl )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.dbl > propVal2->Value.dbl )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.dbl <= propVal2->Value.dbl )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.dbl < propVal2->Value.dbl )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.dbl != propVal2->Value.dbl )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.dbl == propVal2->Value.dbl )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.dbl == propVal2->Value.dbl )
            {
                *result = TRUE;
            }
            break;
        }
        break;

    case PT_BOOLEAN: // b 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.b >= propVal2->Value.b )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.b > propVal2->Value.b )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.b <= propVal2->Value.b )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.b < propVal2->Value.b )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.b != propVal2->Value.b )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.b == propVal2->Value.b )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.b == propVal2->Value.b )
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_CURRENCY: // cur 
        // What's the internal encoding of these two longs? 
        // Need to try this before doing anymore 
        switch( relop )
        {
            // case RELOP_GE:
            //          if( propVal1->Value.cur >= propVal2->Value.cur )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            //if( propVal1->Value.cur. > propVal2->Value.cur )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            // if( propVal1->Value.cur <= propVal2->Value.cur )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            //  if( propVal1->Value.cur == propVal2->Value.cur )
            {
                *result = TRUE;
            }
            break;


        case RELOP_NE:
            //  if( propVal1->Value.cur.Lo != propVal2->Value.cur.Lo
            //        ||  propVal1->Value.cur.Hi != propVal2->Value.cur.Hi)
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            //   if( propVal1->Value.cur.Lo == propVal2->Value.cur.Lo
            //         &&  propVal1->Value.cur.Hi == propVal2->Value.cur.Hi)
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_APPTIME: // at 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.at >= propVal2->Value.at )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.at > propVal2->Value.at )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.at <= propVal2->Value.at )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.at < propVal2->Value.at )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.at != propVal2->Value.at )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.at == propVal2->Value.at )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.at == propVal2->Value.at )
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_SYSTIME: // ft 
        switch( relop )
        {
            //case RELOP_GE:
            //          if( propVal1->Value.ft >= propVal2->Value.ft )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            //    if( propVal1->Value.ft > propVal2->Value.ft )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            //   if( propVal1->Value.ft <= propVal2->Value.ft )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            //   if( propVal1->Value.ft < propVal2->Value.ft )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            //   if( propVal1->Value.ft != propVal2->Value.ft )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            //     if( propVal1->Value.ft == propVal2->Value.ft )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            //      if( propVal1->Value.ft == propVal2->Value.ft )
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_STRING8: // lpszA 
        switch( relop )
        {
        case RELOP_GE:
            if( strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) > 0
                || strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) > 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) < 0
                || strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) < 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( strcmp(propVal1->Value.lpszA, propVal2->Value.lpszA) == 0 )
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_BINARY: // bin 
        res1 =  memcmp(propVal1->Value.bin.lpb, propVal2->Value.bin.lpb, propVal1->Value.bin.cb);
        switch( relop )
        {
        case RELOP_GE:
            if( res1 >= 0  )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( res1 > 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( res1 <= 0  )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( res1 < 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( res1 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( res1 == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( res1 == 0)
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_UNICODE: // lpszW 
        // do I want wcscmp() or mbscmp()? 
        switch( relop )
        {
        case RELOP_GE:
            if( wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) > 0
                || wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) > 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) < 0
                || wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) < 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( wcscmp(propVal1->Value.lpszW, propVal2->Value.lpszW) == 0 )
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_CLSID: // lpguid 
        // there seems to be a few different ways to do this 
        // I'll use memcmp() for now at least 
        switch( relop )
        {
        case RELOP_GE:
            if( memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) > 0
                || memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) > 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) < 0
                || memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) == 0  )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) < 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) == 0 )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( memcmp(propVal1->Value.lpguid, propVal2->Value.lpguid, sizeof(GUID)) == 0)
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

        // case PT_I8: 
    case PT_LONGLONG: // li 
        switch( relop )
        {
            //case RELOP_GE:
            //          if( propVal1->Value.li >= propVal2->Value.li )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            //   if( propVal1->Value.li > propVal2->Value.li )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            //    if( propVal1->Value.li <= propVal2->Value.li )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            //     if( propVal1->Value.li < propVal2->Value.li )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            //     if( propVal1->Value.li != propVal2->Value.li )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            //      if( propVal1->Value.li == propVal2->Value.li )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            //      if( propVal1->Value.li == propVal2->Value.li )
            {
                *result = TRUE;
            }
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_I2: // MVi 
        // if one comparison fails in the array, then the entire operation fails 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVi.cValues;i++)
            {
                if( !(propVal1->Value.MVi.lpi[i] >= propVal2->Value.MVi.lpi[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVi.cValues;i++)
            {
                if( !(propVal1->Value.MVi.lpi[i] > propVal2->Value.MVi.lpi[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVi.cValues;i++)
            {
                if( !(propVal1->Value.MVi.lpi[i] <= propVal2->Value.MVi.lpi[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVi.cValues;i++)
            {
                if( !(propVal1->Value.MVi.lpi[i] < propVal2->Value.MVi.lpi[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVi.cValues;i++)
            {
                if( !(propVal1->Value.MVi.lpi[i] != propVal2->Value.MVi.lpi[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVi.cValues;i++)
            {
                if( !(propVal1->Value.MVi.lpi[i] == propVal2->Value.MVi.lpi[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVi.cValues;i++)
            {
                if( !(propVal1->Value.MVi.lpi[i] == propVal2->Value.MVi.lpi[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_LONG: // MVl 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVl.cValues;i++)
            {
                if( !(propVal1->Value.MVl.lpl[i] >= propVal2->Value.MVl.lpl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVl.cValues;i++)
            {
                if( !(propVal1->Value.MVl.lpl[i] > propVal2->Value.MVl.lpl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVl.cValues;i++)
            {
                if( !(propVal1->Value.MVl.lpl[i] <= propVal2->Value.MVl.lpl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVl.cValues;i++)
            {
                if( !(propVal1->Value.MVl.lpl[i] < propVal2->Value.MVl.lpl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVl.cValues;i++)
            {
                if( !(propVal1->Value.MVl.lpl[i] != propVal2->Value.MVl.lpl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVl.cValues;i++)
            {
                if( !(propVal1->Value.MVl.lpl[i] == propVal2->Value.MVl.lpl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVl.cValues;i++)
            {
                if( !(propVal1->Value.MVl.lpl[i] == propVal2->Value.MVl.lpl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_R4: // MVflt 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVflt.cValues;i++)
            {
                if( !(propVal1->Value.MVflt.lpflt[i] >= propVal2->Value.MVflt.lpflt[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVflt.cValues;i++)
            {
                if( !(propVal1->Value.MVflt.lpflt[i] > propVal2->Value.MVflt.lpflt[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVflt.cValues;i++)
            {
                if( !(propVal1->Value.MVflt.lpflt[i] <= propVal2->Value.MVflt.lpflt[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVflt.cValues;i++)
            {
                if( !(propVal1->Value.MVflt.lpflt[i] < propVal2->Value.MVflt.lpflt[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVflt.cValues;i++)
            {
                if( !(propVal1->Value.MVflt.lpflt[i] != propVal2->Value.MVflt.lpflt[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVflt.cValues;i++)
            {
                if( !(propVal1->Value.MVflt.lpflt[i] == propVal2->Value.MVflt.lpflt[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVflt.cValues;i++)
            {
                if( !(propVal1->Value.MVflt.lpflt[i] == propVal2->Value.MVflt.lpflt[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_DOUBLE: // MVdbl 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVdbl.cValues;i++)
            {
                if( !(propVal1->Value.MVdbl.lpdbl[i] >= propVal2->Value.MVdbl.lpdbl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVdbl.cValues;i++)
            {
                if( !(propVal1->Value.MVdbl.lpdbl[i] > propVal2->Value.MVdbl.lpdbl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVdbl.cValues;i++)
            {
                if( !(propVal1->Value.MVdbl.lpdbl[i] <= propVal2->Value.MVdbl.lpdbl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVdbl.cValues;i++)
            {
                if( !(propVal1->Value.MVdbl.lpdbl[i] < propVal2->Value.MVdbl.lpdbl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVdbl.cValues;i++)
            {
                if( !(propVal1->Value.MVdbl.lpdbl[i] != propVal2->Value.MVdbl.lpdbl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVdbl.cValues;i++)
            {
                if( !(propVal1->Value.MVdbl.lpdbl[i] == propVal2->Value.MVdbl.lpdbl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVdbl.cValues;i++)
            {
                if( !(propVal1->Value.MVdbl.lpdbl[i] == propVal2->Value.MVdbl.lpdbl[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_CURRENCY: // MVcur 
        switch( relop )
        {
            // still not sure about currency 
            // case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVcur.cValues;i++)
            {
                //            if( !(propVal1->Value.MVcur.lpcur[i] >= propVal2->Value.MVcur.lpcur[i]) )
                {
                    failed = TRUE;
                    //           break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVcur.cValues;i++)
            {
                //       if( !(propVal1->Value.MVcur.lpcur[i] > propVal2->Value.MVcur.lpcur[i]) )
                {
                    failed = TRUE;
                    //          break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVcur.cValues;i++)
            {
                //        if( !(propVal1->Value.MVcur.lpcur[i] <= propVal2->Value.MVcur.lpcur[i]) )
                {
                    failed = TRUE;
                    //           break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVcur.cValues;i++)
            {
                //         if( !(propVal1->Value.MVcur.lpcur[i] < propVal2->Value.MVcur.lpcur[i]) )
                {
                    failed = TRUE;
                    //            break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVcur.cValues;i++)
            {
                //     if( !(propVal1->Value.MVcur.lpcur[i].Lo != propVal2->Value.MVcur.lpcur[i].Lo
                //           && propVal1->Value.MVcur.lpcur[i].Hi != propVal2->Value.MVcur.lpcur[i].Hi) )
                {
                    failed = TRUE;
                    //         break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVcur.cValues;i++)
            {
                //        if( !(propVal1->Value.MVcur.lpcur[i].Lo == propVal2->Value.MVcur.lpcur[i].Lo
                //                && propVal1->Value.MVcur.lpcur[i].Hi == propVal2->Value.MVcur.lpcur[i].Hi) )
                {
                    failed = TRUE;
                    //           break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVcur.cValues;i++)
            {
                //          if( !(propVal1->Value.MVcur.lpcur[i].Lo == propVal2->Value.MVcur.lpcur[i].Lo
                //                  && propVal1->Value.MVcur.lpcur[i].Hi == propVal2->Value.MVcur.lpcur[i].Hi) )
                {
                    failed = TRUE;
                    //             break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_APPTIME: // MVat 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVat.cValues;i++)
            {
                if( !(propVal1->Value.MVat.lpat[i] >= propVal2->Value.MVat.lpat[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVat.cValues;i++)
            {
                if( !(propVal1->Value.MVat.lpat[i] > propVal2->Value.MVat.lpat[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVat.cValues;i++)
            {
                if( !(propVal1->Value.MVat.lpat[i] <= propVal2->Value.MVat.lpat[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVat.cValues;i++)
            {
                if( !(propVal1->Value.MVat.lpat[i] < propVal2->Value.MVat.lpat[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVat.cValues;i++)
            {
                if( !(propVal1->Value.MVat.lpat[i] != propVal2->Value.MVat.lpat[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVat.cValues;i++)
            {
                if( !(propVal1->Value.MVat.lpat[i] == propVal2->Value.MVat.lpat[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVat.cValues;i++)
            {
                if( !(propVal1->Value.MVat.lpat[i] == propVal2->Value.MVat.lpat[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_SYSTIME: // MVft 
        switch( relop )
        {
            //case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVft.cValues;i++)
            {
                //            if( !(propVal1->Value.MVft.lpft[i] >= propVal2->Value.MVft.lpft[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVft.cValues;i++)
            {
                //            if( !(propVal1->Value.MVft.lpft[i] > propVal2->Value.MVft.lpft[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVft.cValues;i++)
            {
                //            if( !(propVal1->Value.MVft.lpft[i] <= propVal2->Value.MVft.lpft[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVft.cValues;i++)
            {
                //            if( !(propVal1->Value.MVft.lpft[i] < propVal2->Value.MVft.lpft[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVft.cValues;i++)
            {
                //            if( !(propVal1->Value.MVft.lpft[i] != propVal2->Value.MVft.lpft[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVft.cValues;i++)
            {
                //            if( !(propVal1->Value.MVft.lpft[i] == propVal2->Value.MVft.lpft[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVft.cValues;i++)
            {
                //            if( !(propVal1->Value.MVft.lpft[i] == propVal2->Value.MVft.lpft[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_BINARY: // MVbin 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVbin.cValues;i++)
            {
                if( !( memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) > 0
                    || memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVbin.cValues;i++)
            {
                if( !( memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) > 0 ) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVbin.cValues;i++)
            {
                if( !( memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) < 0
                    || memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVbin.cValues;i++)
            {
                if( !( memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) < 0 ) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVbin.cValues;i++)
            {
                if( !( memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) != 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVbin.cValues;i++)
            {
                if( !( memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVbin.cValues;i++)
            {
                if( !( memcmp(propVal1->Value.MVbin.lpbin[i].lpb, propVal2->Value.MVbin.lpbin[i].lpb, propVal1->Value.MVbin.lpbin[i].cb) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_STRING8: // MVszA 
        // jagged array 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszA.cValues;i++)
            {
                if( !( strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) > 0
                    || strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszA.cValues;i++)
            {
                if( !( strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) > 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszA.cValues;i++)
            {
                if( !( strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) < 0
                    || strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszA.cValues;i++)
            {
                if( !( strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) < 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszA.cValues;i++)
            {
                if( !( strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) ) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszA.cValues;i++)
            {
                if( !( strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i])== 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszA.cValues;i++)
            {
                if( !( strcmp(propVal1->Value.MVszA.lppszA[i], propVal2->Value.MVszA.lppszA[i]) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_UNICODE: // MVszW 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszW.cValues;i++)
            {
                if( !( wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i]) > 0
                    || wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i]) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszW.cValues;i++)
            {
                if( !( wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i]) > 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszW.cValues;i++)
            {
                if( !( wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i]) < 0
                    || wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i]) == 0) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszW.cValues;i++)
            {
                if( !( wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i]) < 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszW.cValues;i++)
            {
                if( !( wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i])))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszW.cValues;i++)
            {
                if( !( wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i])))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVszW.cValues;i++)
            {
                if( !( wcscmp(propVal1->Value.MVszW.lppszW[i], propVal2->Value.MVszW.lppszW[i])== 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_CLSID: // MVguid 
        switch( relop )
        {
        case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVguid.cValues;i++)
            {
                if( !( memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) > 0 
                    || memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) == 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVguid.cValues;i++)
            {
                if( !( memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) > 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVguid.cValues;i++)
            {
                if( !( memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) < 0 
                    || memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) == 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVguid.cValues;i++)
            {
                if( !( memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) < 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVguid.cValues;i++)
            {
                if( !( memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) != 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVguid.cValues;i++)
            {
                if( !( memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) == 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVguid.cValues;i++)
            {
                if( !( memcmp(&(propVal1->Value.MVguid.lpguid[i]), &(propVal2->Value.MVguid.lpguid[i]), sizeof(GUID)) == 0 ))
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        default:
            // error condition 
            break;
        }
        break;

    case PT_MV_I8: // MVli 
        switch( relop )
        {
            //case RELOP_GE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVli.cValues;i++)
            {
                //            if( !(propVal1->Value.MVli.lpli[i] >= propVal2->Value.MVli.lpli[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_GT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVli.cValues;i++)
            {
                //            if( !(propVal1->Value.MVli.lpli[i] > propVal2->Value.MVli.lpli[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVli.cValues;i++)
            {
                //            if( !(propVal1->Value.MVli.lpli[i] <= propVal2->Value.MVli.lpli[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_LT:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVli.cValues;i++)
            {
                //            if( !(propVal1->Value.MVli.lpli[i] < propVal2->Value.MVli.lpli[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_NE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVli.cValues;i++)
            {
                //            if( !(propVal1->Value.MVli.lpli[i] != propVal2->Value.MVli.lpli[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_RE:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVli.cValues;i++)
            {
                //            if( !(propVal1->Value.MVli.lpli[i] == propVal2->Value.MVli.lpli[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break;

        case RELOP_EQ:
            failed=FALSE;
            for(ULONG i=0;i<propVal1->Value.MVli.cValues;i++)
            {
                //            if( !(propVal1->Value.MVli.lpli[i] == propVal2->Value.MVli.lpli[i]) )
                {
                    failed = TRUE;
                    break;
                }
            }
            *result = failed?MAPI_E_NOT_FOUND:S_OK;
            break; 

        default:
            // error condition 
            retVal = MAPI_E_CALL_FAILED;
            break;
        }
        break;

    case PT_ERROR: // err 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.err >= propVal2->Value.err )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.err > propVal2->Value.err )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.err <= propVal2->Value.err )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.err < propVal2->Value.err )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.err != propVal2->Value.err )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.err == propVal2->Value.err )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.err == propVal2->Value.err )
            {
                *result = TRUE;
            }
            break;
        }
        break;

    case PT_NULL:
    case PT_OBJECT: // x 
        switch( relop )
        {
        case RELOP_GE:
            if( propVal1->Value.x >= propVal2->Value.x )
            {
                *result = TRUE;
            }
            break;

        case RELOP_GT:
            if( propVal1->Value.x > propVal2->Value.x )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LE:
            if( propVal1->Value.x <= propVal2->Value.x )
            {
                *result = TRUE;
            }
            break;

        case RELOP_LT:
            if( propVal1->Value.x < propVal2->Value.x )
            {
                *result = TRUE;
            }
            break;

        case RELOP_NE:
            if( propVal1->Value.x != propVal2->Value.x )
            {
                *result = TRUE;
            }
            break;

        case RELOP_RE:
            if( propVal1->Value.x == propVal2->Value.x )
            {
                *result = TRUE;
            }
            break;

        case RELOP_EQ:
            if( propVal1->Value.x == propVal2->Value.x )
            {
                *result = TRUE;
            }
            break;
        }
        break;

    default:
        // error condition 
        *result = failed?MAPI_E_NOT_FOUND:S_OK;
        retVal = E_FAIL;
        break;
    }

    return retVal;
}
